﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using XChipTool.Enties;

namespace BinAnalysisHelp
{
   public class BinUtilsHelp
    {
        public static bool IsOutput { get; private set; } = false;
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        /// <summary>
        /// 打开指定路径的 Bin 文件并处理相关数据
        /// </summary>
        /// <param name="path">Bin 文件的路径</param>
        /// <param name="xclist">xc151binparsing 对象列表</param>
        /// <param name="BinList">BinBase 对象列表</param>
        /// <param name="lspList">LoadSettingParse 对象列表</param>
        /// <param name="usbList">SettingFileIDInfo 对象列表</param>
        /// <param name="isUsb">是否为 USB 设备，默认为 false</param>
        public static void OpenBinFile(string path, List<xc151binparsing> xclist,ref List<BinBase> BinList,ref List<LoadSettingParse> lspList,ref List<SettingFileIDInfo> usbList, bool isUsb = false)
        {
            // 检查文件路径是否有效
            if (string.IsNullOrEmpty(path) || !File.Exists(path))
            {
                throw new FileNotFoundException("指定的文件未找到", path);
            }

            // 从 Bin 文件读取数据并转换为 BinBase 列表
            BinList = BinToList(path);
            Thread.Sleep(1); // 暂停以确保数据处理的稳定性

            // 将 BinBase 列表转换为 xc151binparsing 对象
            BinList = BinBaseToNode(BinList, xclist);
            Thread.Sleep(1); // 暂停以确保数据处理的稳定性

            // 将 BinBase 列表转换为 ISP 格式
            BinList = BinBaseToIsp(BinList);
            Thread.Sleep(1); // 暂停以确保数据处理的稳定性

            // 设置 ISP 模式
            SetModeIsp(ref BinList);
            Thread.Sleep(1); // 暂停以确保数据处理的稳定性

            // 根据配置决定加载不同的设置
            var configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var isSerialSetting = configuration.AppSettings.Settings["IsSerial"]?.Value;

            if (isSerialSetting == "TVE")
            {
                // 解析设置
                SetLoadSetting(ref BinList,ref lspList);
            }
            else
            {
                // 过滤出适合处理的设置区域
                var tlist = BinList.Where(c => !string.IsNullOrEmpty(c.note) && c.note.Contains("setting区1_31_") && !c.note.Contains("_en") && !c.module.Contains("Header")).ToList();

                // 创建 Setting1_31Parser 实例并加载设置
                Setting1_31Parser s1_31 = new Setting1_31Parser();
                s1_31.LoadSettingData(tlist.Select(c => c.original).ToList());

                // 获取 USB 文件 ID 信息
                usbList = s1_31.GetFileIDInfo();
            }
        }



        /// <summary>
        /// 读取文件并将其内容解析为 BinBase 对象的列表
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="isbool">标志，指示地址和数据的顺序</param>
        /// <returns>解析后的 BinBase 对象列表</returns>
        public static List<BinBase> BinToList(string path, bool isbool = false)
        {
            List<BinBase> blist = new List<BinBase>(); // 存储解析后的 BinBase 对象列表

            try
            {
                // 读取文件字节并转换为列表
                var list = System.IO.File.ReadAllBytes(path).ToList();

                // 初始化辅助变量
                string fffd = ""; // 地址部分
                string fffe = ""; // 数据部分
                string exdata = string.Empty; // 额外数据
                int i = 0; // 当前索引

                while (i < list.Count)
                {
                    // 确保有足够的字节进行处理
                    if (i + 4 <= list.Count)
                    {
                        // 定义大地址和小地址的数据字符串
                        string bigaddrT, bigdataT, smalladdrT, smalldataT;

                        if (isbool)
                        {
                            // 如果 isbool 为 true，使用特定的字节顺序
                            bigaddrT = $"{list[i]:X2}{list[i + 1]:X2}"; // 大地址
                            bigdataT = $"{list[i + 2]:X2}{list[i + 3]:X2}"; // 大数据
                            smalladdrT = $"{list[i + 1]:X2}{list[i]:X2}"; // 小地址
                            smalldataT = $"{list[i + 3]:X2}{list[i + 2]:X2}"; // 小数据
                        }
                        else
                        {
                            // 如果 isbool 为 false，使用另一种字节顺序
                            bigaddrT = $"{list[i + 2]:X2}{list[i + 3]:X2}"; // 大地址
                            bigdataT = $"{list[i]:X2}{list[i + 1]:X2}"; // 大数据
                            smalladdrT = $"{list[i + 3]:X2}{list[i + 2]:X2}"; // 小地址
                            smalldataT = $"{list[i + 1]:X2}{list[i]:X2}"; // 小数据
                        }

                        // 创建4个 BinBase 对象，表示当前字节的不同部分
                        for (int j = 0; j < 4; j++)
                        {
                            BinBase model = new BinBase
                            {
                                original = list[i], // 原始字节
                                bigaddr = bigaddrT, // 大地址
                                smalladdr = smalladdrT, // 小地址
                                bigdata = bigdataT, // 大数据
                                smalldata = smalldataT, // 小数据
                                sort = j, // 排序索引
                                AnalyticalModel = exdata, // 解析模型（可以根据需要调整）
                                AddrVal = j > 1 ? AddressValueEnum.Addr : AddressValueEnum.Val // 地址值枚举
                            };

                            // 如果地址部分不为空，则进行组合
                            if (!string.IsNullOrEmpty(fffd) && !string.IsNullOrEmpty(fffe))
                            {
                                model.addresspart = $"{Convert.ToUInt16(fffd, 16):X2}{Convert.ToUInt16(fffe, 16):X2}";
                            }

                            // 将模型添加到列表中
                            blist.Add(model);
                            i++; // 移动到下一个字节
                        }
                    }
                    else
                    {
                        // 如果剩余字节不足，跳出循环
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                // 记录异常信息
                logger.Error($"{ex.Message}");
            }

            return blist; // 返回解析后的对象列表
        }

        /// <summary>
        /// 赋值 BinBase 对象属性值
        /// </summary>
        /// <param name="blist">BinBase 对象列表</param>
        /// <param name="xclist">解析参数列表</param>
        /// <returns>更新后的 BinBase 对象列表</returns>
        public static List<BinBase> BinBaseToNode(List<BinBase> blist, List<xc151binparsing> xclist)
        {
            const int headKey = 0x368; // 头文件开始的索引
            const int headLength = 0x320; // 头文件长度

            // 解析头文件的起始地址
            var HeadStartAddr = Convert.ToUInt32("0x" + blist[headKey + 1].original.ToString("X2") + blist[headKey].original.ToString("X2"), 16);
            var HeadEndAddr = HeadStartAddr + headLength; // 头文件结束地址

            int no = 0; // xc151binparsing 列表索引
            for (int i = Convert.ToInt32(HeadStartAddr); i < HeadEndAddr; i++)
            {
                // 如果处于 CRC 区域
                if (i >= HeadEndAddr - 4)
                {
                    for (int j = i; j < HeadEndAddr; j++)
                    {
                        blist[j].describe = "crc"; // 描述设置为 crc
                        blist[j].remarks = "头文件crc"; // 备注设置为头文件crc
                        blist[j].crcold =
                            $"{blist[i].original:X}{blist[i + 1].original:X}{blist[i + 2].original:X}{blist[i + 3].original:X}"; // 旧的 CRC 值
                        blist[j].crchead = HeadStartAddr.ToString(); // CRC 开始地址
                        blist[j].crctail = (HeadEndAddr - 4).ToString(); // CRC 结束地址
                        blist[j].module = "Header"; // 模块设置为 Header
                        blist[j].note = "Header_crc"; // 备注为 Header_crc
                        blist[i].section = "Header_crc"; // 部分设置为 Header_crc
                    }
                    i += 2; // 跳过后续两个索引
                }
                else
                {
                    // 从 xclist 中赋值属性
                    blist[i].address = xclist[no].address;
                    blist[i].describe = xclist[no].describe;
                    blist[i].dataexample = xclist[no].dataexample;
                    blist[i].module = xclist[no].module;
                    blist[i].section = xclist[no].section;
                    blist[i].note = xclist[no].note;
                    no++; // 移动到下一个 xc151binparsing 项
                }
            }

            // 过滤出模块为 Header 且不包含 "_en" 的项
            var headList = blist.Where(c => c.module == "Header" && !string.IsNullOrEmpty(c.note) && !c.note.Contains("_en") && c.smalldata != "0000").ToList();
            var shead = headList.Select(c => c.note).Distinct().ToList(); // 获取唯一的 note 列表

            // 遍历每个头部描述
            for (int i = 0; i < shead.Count(); i++)
            {
                // 排除特定的条目
                if (shead[i].ToLower().Contains("pu_ct") || shead[i].ToLower().Contains("boot_log") || shead[i].ToLower().Contains("header_crc"))
                    continue;

                // 查找当前 note 的最后一个模型
                var model = blist.FindLast(c => c.module == "Header" && c.note == shead[i] && !c.note.Contains("_crc"));
                int listAddr = model != null ? Convert.ToInt32(model.smalldata, 16) : 0; // 获取地址
                int listnextAddr = 0;

                // 获取下一个 note 的地址
                if (i + 1 < shead.Count())
                {
                    var sData = blist.FindLast(c => c.module == "Header" && c.note == shead[i + 1] && !c.note.Contains("_crc"));
                    listnextAddr = (sData == null || sData.smalldata == "FFFF") ? blist.Count() : Convert.ToInt32(sData.smalldata, 16);
                }

                // 如果地址超出范围则跳过
                if (listAddr > blist.Count())
                {
                    continue;
                }

                // 解析视频设置区
                if (shead[i].Contains("App setting区") && blist.GetRange(listAddr, listnextAddr - listAddr).Exists(c => c.smalladdr.ToLower() == "fff5"))
                {
                    // 查找 'fff5' 的索引并继续处理
                    var indexT = blist.GetRange(listAddr, listnextAddr - listAddr).FindIndex(c => c.smalladdr.ToLower() == "fff5") + listAddr + 4;
                }

                // 为每个区域赋值属性
                for (int j = listAddr; j < listnextAddr; j++)
                {
                    blist[j].module = model.section; // 使用模型的部分
                    blist[j].note = model.note; // 使用模型的备注
                    blist[j].VideoHex = string.Empty; // 视频十六进制，初始为空
                    blist[j].TransferHex = string.Empty; // 传输十六进制，初始为空
                    blist[j].IdxHex = string.Empty; // 索引十六进制，初始为空

                    // CRC 处理
                    if (blist[j].smalladdr.ToLower() == "fff5" || blist[j].bigaddr.ToLower() == "fff5")
                    {
                        blist[j].describe = "crc"; // 描述设置为 crc
                        blist[j].remarks = $"{model.note}_crc"; // 备注为模型的 note 加上 _crc
                        blist[j].crcold = blist[j].bigaddr.ToLower() == "fff5" ? blist[j].bigdata : blist[j].smalldata; // 旧的 CRC 值
                        blist[j].crchead = listAddr.ToString(); // CRC 开始地址
                        blist[j].crctail = (listAddr + 8).ToString(); // CRC 结束地址
                        blist[j].crclength = "8"; // CRC 长度
                    }
                    else if (blist[j].bigaddr.ToLower() == "f6f5" || blist[j].smalladdr.ToLower() == "f6f5") // 修改 f6f5 长度
                    {
                        blist[j].describe = "crc"; // 描述设置为 crc
                        blist[j].remarks = $"{model.note}_crc"; // 备注为模型的 note 加上 _crc
                        blist[j].crcold = blist[j].bigaddr.ToLower() == "f6f5" ? blist[j].bigdata : blist[j].smalldata; // 旧的 CRC 值
                        blist[j].crchead = j.ToString(); // CRC 开始地址
                        blist[j].crctail = (listAddr + 256).ToString(); // CRC 结束地址
                        blist[j].crclength = "256"; // CRC 长度
                    }
                }
            }

            return blist; // 返回更新后的 BinBase 对象列表
        }

        /// <summary>
        /// 将 BinBase 列表转换为 ISP 格式
        /// </summary>
        /// <param name="blist">BinBase 列表</param>
        /// <param name="isbool">是否反转字节顺序（默认 false）</param>
        /// <returns>处理后的 BinBase 列表</returns>
        public static List<BinBase> BinBaseToIsp(List<BinBase> blist, bool isbool = false)
        {
            // 输出结果到文件的开关
            if (IsOutput)
            {
                using (StreamWriter writer = new StreamWriter($"{System.IO.Directory.GetCurrentDirectory()}\\Lib\\xc151_Bin\\A_BListSetting.txt"))
                {
                    // 将 blist 中的每个元素写入到文本文件
                    foreach (var item in blist)
                    {
                        writer.WriteLine($"{item.bigaddr}_{item.smalladdr}_{item.smalldata}_{item.bigexample}_{item.bigexample}_{item.smallexample}_{item.AnalyticalModel}_{item.AddrVal}_{item.addresspart}{item.addrsmallex}");
                    }
                }
            }

            // 查找 setting 区的起始和结束索引
            var startHeaderIndex = blist.FindIndex(c => c.note != null && c.note.Contains("setting区0_00_首地址"));
            var endHeaderIndex = blist.FindLastIndex(c => c.note != null && c.note.Contains("Header_crc"));

            // 计算需要的数量
            var nums = endHeaderIndex - startHeaderIndex;

            // 获取需要处理的 'App setting区' 的说明
            var appENList = blist.Where(c => c.note != null && c.note.Contains("App setting区") && c.note.Contains("_en") && c.original == 1)
                .Select(c => c.note.Replace("_en", ""))
                .Distinct()
                .ToList();

            // 生成需要处理的结果列表
            var result = blist.Skip(startHeaderIndex).Take(nums)
                .Where(c => c.note != null && c.sort == 0x3 && appENList.Any(b => c.note.Contains(b)))
                .ToList();

            // 初始化辅助变量
            string fffd = "";
            string fffe = "";
            string fff6 = "";
            bool f6bool = false;
            double fff7 = 0;
            bool f7bool = false;
            int bigsmall = -1; // -1表示默认，0表示big，1表示small
            string exdata = string.Empty;

            // 遍历结果集，进行解析
            foreach (var item in result)
            {
                // 将小数据转换为整数
                var sdata = Convert.ToInt32(item.smalldata, 16);
                if (blist.Count <= sdata)
                {
                    continue; // 如果索引超出范围，则跳过
                }

                // 获取相关数据
                var t = blist[sdata];
                var t1 = blist[sdata + 4];
                int count = 0;

                // 统计需要解析的数据
                if (t.smalladdr == "5843" && t.smalldata == "0151" && t1.smalldata != "0000")
                {
                    count = Convert.ToInt32(t1.smalldata, 16) * 4;
                }

                // 获取需要解析的数据范围
                var sResult = blist.Skip(sdata).Take(count).ToList();
                var scount = sdata + count;

                for (int i = sdata; i < sdata + count;)
                {
                    // 设置为文件内容
                    blist[i].IsSetting = true;

                    // 确保不会越界
                    if (i + 4 <= scount)
                    {
                        string bigaddrT = string.Empty;
                        string bigdataT = string.Empty;
                        string smalladdrT = string.Empty;
                        string smalldataT = string.Empty;

                        // 根据 isbool 确定地址和数据的顺序
                        if (isbool)
                        {
                            bigaddrT = $"{blist[i].original:X2}{blist[i + 1].original:X2}";
                            bigdataT = $"{blist[i + 2].original:X2}{blist[i + 3].original:X2}";
                            smalladdrT = $"{blist[i + 1].original:X2}{blist[i].original:X2}";
                            smalldataT = $"{blist[i + 3].original:X2}{blist[i + 2].original:X2}";
                        }
                        else
                        {
                            bigaddrT = $"{blist[i + 2].original:X2}{blist[i + 3].original:X2}";
                            bigdataT = $"{blist[i].original:X2}{blist[i + 1].original:X2}";
                            smalladdrT = $"{blist[i + 3].original:X2}{blist[i + 2].original:X2}";
                            smalldataT = $"{blist[i + 1].original:X2}{blist[i].original:X2}";
                        }

                        // 处理特定地址
                        if (bigaddrT.Equals("fffd", StringComparison.OrdinalIgnoreCase) || smalladdrT.Equals("fffd", StringComparison.OrdinalIgnoreCase))
                        {
                            fffd = bigaddrT.Equals("fffd", StringComparison.OrdinalIgnoreCase) ? bigdataT : smalldataT;
                        }
                        else if (bigaddrT.Equals("fffe", StringComparison.OrdinalIgnoreCase) || smalladdrT.Equals("fffe", StringComparison.OrdinalIgnoreCase))
                        {
                            fffe = bigaddrT.Equals("fffe", StringComparison.OrdinalIgnoreCase) ? bigdataT : smalldataT;
                        }
                        else if (bigaddrT.Equals("fff6", StringComparison.OrdinalIgnoreCase) || smalladdrT.Equals("fff6", StringComparison.OrdinalIgnoreCase))
                        {
                            fff6 = bigaddrT.Equals("fff6", StringComparison.OrdinalIgnoreCase) ? bigdataT : smalldataT;
                            f6bool = true;
                            bigsmall = bigaddrT.Equals("fff6", StringComparison.OrdinalIgnoreCase) ? 0 : 1;
                        }
                        else if (bigaddrT.Equals("fff5", StringComparison.OrdinalIgnoreCase) || smalladdrT.Equals("fff5", StringComparison.OrdinalIgnoreCase))
                        {
                            for (int j = 0; j < 4; j++)
                            {
                                blist[i].IsSetting = true;
                                blist[i].bigaddr = bigaddrT;
                                blist[i].smalladdr = smalladdrT;
                                blist[i].bigdata = bigdataT;
                                blist[i].smalldata = smalldataT;
                                blist[i].sort = j;
                                blist[i].AddrVal = j > 1 ? AddressValueEnum.Addr : AddressValueEnum.Val;
                                if (!string.IsNullOrEmpty(fffd) && !string.IsNullOrEmpty(fffe))
                                {
                                    blist[i].addresspart = $"{Convert.ToUInt16(fffd, 16):X2}{Convert.ToUInt16(fffe, 16):X2}";
                                }
                                i++;
                            }
                            continue; // 处理完毕，继续外层循环
                        }
                        else if (bigaddrT.Equals("f6f5", StringComparison.OrdinalIgnoreCase) || smalladdrT.Equals("f6f5", StringComparison.OrdinalIgnoreCase))
                        {
                            for (int j = 0; j < 4; j++)
                            {
                                blist[i].IsSetting = true;
                                blist[i].bigaddr = bigaddrT;
                                blist[i].smalladdr = smalladdrT;
                                blist[i].bigdata = bigdataT;
                                blist[i].smalldata = smalldataT;
                                blist[i].sort = j;
                                blist[i].AddrVal = j > 1 ? AddressValueEnum.Addr : AddressValueEnum.Val;
                                if (!string.IsNullOrEmpty(fffd) && !string.IsNullOrEmpty(fffe))
                                {
                                    blist[i].addresspart = $"{Convert.ToUInt16(fffd, 16):X2}{Convert.ToUInt16(fffe, 16):X2}";
                                }
                                i++;
                            }
                            continue; // 处理完毕，继续外层循环
                        }

                        // 处理 f6bool 逻辑
                        if (f6bool)
                        {
                            string bigaddrNT, bigdataNT, smalladdrNT, smalldataNT;
                            if (isbool)
                            {
                                bigaddrNT = $"{blist[i + 4].original:X2}{blist[i + 1 + 4].original:X2}";
                                bigdataNT = $"{blist[i + 2 + 4].original:X2}{blist[i + 3 + 4].original:X2}";
                                smalladdrNT = $"{blist[i + 1 + 4].original:X2}{blist[i + 4].original:X2}";
                                smalldataNT = $"{blist[i + 3 + 4].original:X2}{blist[i + 2 + 4].original:X2}";
                            }
                            else
                            {
                                bigaddrNT = $"{blist[i + 2 + 4].original:X2}{blist[i + 3 + 4].original:X2}";
                                bigdataNT = $"{blist[i + 4].original:X2}{blist[i + 1 + 4].original:X2}";
                                smalladdrNT = $"{blist[i + 3 + 4].original:X2}{blist[i + 2 + 4].original:X2}";
                                smalldataNT = $"{blist[i + 1 + 4].original:X2}{blist[i + 4].original:X2}";
                            }

                            // 解析地址并构建示例
                            if (bigaddrNT.Equals("fff7", StringComparison.OrdinalIgnoreCase) || smalladdrNT.Equals("fff7", StringComparison.OrdinalIgnoreCase))
                            {
                                fff7 = Convert.ToInt32(bigaddrNT.Equals("fff7", StringComparison.OrdinalIgnoreCase) ? bigdataNT : smalldataNT, 16);
                                f7bool = true;
                                f6bool = false;
                                bigsmall = bigaddrNT.Equals("fff7", StringComparison.OrdinalIgnoreCase) ? 0 : 1;
                            }

                            string example = string.Empty;
                            exdata = string.Empty;

                            if (bigsmall == 0)
                            {
                                switch (bigdataT.Substring(bigdataT.Length - 2))
                                {
                                    case "01":
                                    case "02":
                                        exdata = "03";
                                        break;
                                    case "03":
                                        exdata = "05";
                                        break;
                                    case "04":
                                        exdata = "06";
                                        break;
                                    case "05":
                                        exdata = "07";
                                        break;
                                    default:
                                        exdata = smalldataT.Substring(smalldataT.Length - 2);
                                        break;
                                }
                                example = $"0xfff8,0x{bigdataT.Substring(0, 2)},0xfffe,0x{exdata},";
                            }
                            else if (bigsmall == 1)
                            {
                                switch (smalldataT.Substring(smalldataT.Length - 2))
                                {
                                    case "01":
                                    case "02":
                                        exdata = "03";
                                        break;
                                    case "03":
                                        exdata = "05";
                                        break;
                                    case "04":
                                        exdata = "06";
                                        break;
                                    case "05":
                                        exdata = "07";
                                        break;
                                    default:
                                        exdata = smalldataT.Substring(smalldataT.Length - 2);
                                        break;
                                }
                                example = $"0xfff8,0x{smalldataT.Substring(0, 2)},\n0xfffe,0x{exdata},";
                            }

                            // 填充 blist 数据
                            for (int j = 0; j < 4; j++)
                            {
                                blist[i].IsSetting = true;
                                blist[i].bigaddr = bigaddrT;
                                blist[i].smalladdr = smalladdrT;
                                blist[i].bigdata = bigdataT;
                                blist[i].smalldata = smalldataT;
                                blist[i].bigexample = example;
                                blist[i].smallexample = example;
                                blist[i].AnalyticalModel = exdata;
                                blist[i].sort = j;
                                blist[i].AddrVal = j > 1 ? AddressValueEnum.Addr : AddressValueEnum.Val;
                                if (!string.IsNullOrEmpty(fffd) && !string.IsNullOrEmpty(fffe))
                                {
                                    blist[i].addresspart = $"{Convert.ToUInt16(fffd, 16):X2}{Convert.ToUInt16(fffe, 16):X2}";
                                }
                                i++;
                            }

                            // 填充第二组数据
                            for (int j = 0; j < 4; j++)
                            {
                                blist[i].IsSetting = true;
                                blist[i].bigaddr = bigaddrNT;
                                blist[i].smalladdr = smalladdrNT;
                                blist[i].bigdata = bigdataNT;
                                blist[i].smalldata = smalldataNT;
                                blist[i].AnalyticalModel = exdata;
                                blist[i].sort = j;
                                blist[i].AddrVal = j > 1 ? AddressValueEnum.Addr : AddressValueEnum.Val;
                                if (!string.IsNullOrEmpty(fffd) && !string.IsNullOrEmpty(fffe))
                                {
                                    blist[i].addresspart = $"{Convert.ToUInt16(fffd, 16):X2}{Convert.ToUInt16(fffe, 16):X2}";
                                }
                                i++;
                            }
                        }
                        else if (f7bool)
                        {
                            // 处理 f7bool 逻辑
                            if (exdata == "00")
                            {
                                // 设置地址和数据
                                if (isbool)
                                {
                                    bigaddrT = $"{blist[i + 1].original:X2}";
                                    bigdataT = $"{blist[i].original:X2}";
                                    smalladdrT = $"{blist[i].original:X2}";
                                    smalldataT = $"{blist[i + 1].original:X2}";
                                }
                                else
                                {
                                    bigaddrT = $"{blist[i].original:X2}";
                                    bigdataT = $"{blist[i + 1].original:X2}";
                                    smalladdrT = $"{blist[i + 1].original:X2}";
                                    smalldataT = $"{blist[i].original:X2}";
                                }

                                // 填充数据
                                for (int j = 0; j < 2; j++)
                                {
                                    blist[i].IsSetting = true;
                                    blist[i].bigaddr = bigaddrT;
                                    blist[i].smalladdr = smalladdrT;
                                    blist[i].bigdata = bigdataT;
                                    blist[i].smalldata = smalldataT;
                                    blist[i].sort = j;
                                    blist[i].AnalyticalModel = exdata;
                                    blist[i].AddrVal = j > 0 ? AddressValueEnum.Addr : AddressValueEnum.Val;
                                    if (!string.IsNullOrEmpty(fffd) && !string.IsNullOrEmpty(fffe))
                                    {
                                        blist[i].addresspart = $"{Convert.ToUInt16(fffd, 16):X2}{Convert.ToUInt16(fffe, 16):X2}";
                                    }
                                    i++;
                                }
                                fff7 -= 1; // 更新 fff7 计数
                            }
                            else if (exdata == "03")
                            {
                                // 填充 4 个数据
                                for (int j = 0; j < 4; j++)
                                {
                                    blist[i].IsSetting = true;
                                    blist[i].bigaddr = bigaddrT;
                                    blist[i].smalladdr = smalladdrT;
                                    blist[i].bigdata = bigdataT;
                                    blist[i].smalldata = smalldataT;
                                    blist[i].sort = j;
                                    blist[i].AnalyticalModel = exdata;
                                    blist[i].AddrVal = j > 1 ? AddressValueEnum.Addr : AddressValueEnum.Val;
                                    if (!string.IsNullOrEmpty(fffd) && !string.IsNullOrEmpty(fffe))
                                    {
                                        blist[i].addresspart = $"{Convert.ToUInt16(fffd, 16):X2}{Convert.ToUInt16(fffe, 16):X2}";
                                    }
                                    i++;
                                }
                                fff7 -= 1; // 更新 fff7 计数
                            }
                            else
                            {
                                // 设置地址和数据
                                string bigaddrNT, bigdataNT, smalladdrNT, smalldataNT;
                                if (isbool)
                                {
                                    bigaddrNT = $"{blist[i + 4].original:X2}{blist[i + 1 + 4].original:X2}";
                                    bigdataNT = $"{blist[i + 2 + 4].original:X2}{blist[i + 3 + 4].original:X2}";
                                    smalladdrNT = $"{blist[i + 1 + 4].original:X2}{blist[i + 4].original:X2}";
                                    smalldataNT = $"{blist[i + 3 + 4].original:X2}{blist[i + 2 + 4].original:X2}";
                                }
                                else
                                {
                                    bigaddrNT = $"{blist[i + 2 + 4].original:X2}{blist[i + 3 + 4].original:X2}";
                                    bigdataNT = $"{blist[i + 4].original:X2}{blist[i + 1 + 4].original:X2}";
                                    smalladdrNT = $"{blist[i + 3 + 4].original:X2}{blist[i + 2 + 4].original:X2}";
                                    smalldataNT = $"{blist[i + 1 + 4].original:X2}{blist[i + 4].original:X2}";
                                }

                                // 初始化示例
                                string example = string.Empty;
                                string addrEx = string.Empty;

                                // 构建示例
                                if (bigsmall == 0)
                                {
                                    addrEx = bigaddrT;
                                    example = $"0xffe0,0x{bigaddrT},\n0xffe1,0x{bigdataT},\n0xffe2,0x{bigaddrNT},\n0xffe3,0x{bigdataNT},";
                                }
                                else if (bigsmall == 1)
                                {
                                    addrEx = smalladdrT;
                                    example = $"0xffe0,0x{smalladdrT},\n0xffe1,0x{smalldataT},\n0xffe2,0x{smalladdrNT},\n0xffe3,0x{smalldataNT},";
                                }

                                // 填充 8 个数据
                                for (int j = 0; j < 8; j++)
                                {
                                    blist[i].IsSetting = true;
                                    blist[i].bigaddr = bigdataT;
                                    blist[i].smalladdr = smalldataT;
                                    blist[i].bigdata = bigaddrNT + bigdataNT;
                                    blist[i].smalldata = smalladdrNT + smalldataNT;
                                    blist[i].addresspart = addrEx;
                                    blist[i].bigexample = example;
                                    blist[i].smallexample = example;
                                    blist[i].sort = j;
                                    blist[i].AnalyticalModel = exdata;
                                    blist[i].AddrVal = j > 3 ? AddressValueEnum.Val : AddressValueEnum.Addr;
                                    if (!string.IsNullOrEmpty(fffd) && !string.IsNullOrEmpty(fffe))
                                    {
                                        blist[i].addresspart = $"{Convert.ToUInt16(fffd, 16):X2}{Convert.ToUInt16(fffe, 16):X2}";
                                    }
                                    i++;
                                }

                                fff7 -= 2; // 更新 fff7 计数
                            }

                            // 检查 fff7 是否小于等于 0
                            if (fff7 <= 0)
                            {
                                f7bool = false;
                                f6bool = false;
                                bigsmall = -1;
                                exdata = string.Empty;
                            }
                        }
                        else
                        {
                            // 填充 4 个数据
                            for (int j = 0; j < 4; j++)
                            {
                                blist[i].IsSetting = true;
                                blist[i].bigaddr = bigaddrT;
                                blist[i].smalladdr = smalladdrT;
                                blist[i].bigdata = bigdataT;
                                blist[i].smalldata = smalldataT;
                                blist[i].sort = j;
                                blist[i].AnalyticalModel = exdata;
                                blist[i].AddrVal = j > 1 ? AddressValueEnum.Addr : AddressValueEnum.Val;
                                if (!string.IsNullOrEmpty(fffd) && !string.IsNullOrEmpty(fffe))
                                {
                                    blist[i].addresspart = $"{Convert.ToUInt16(fffd, 16):X2}{Convert.ToUInt16(fffe, 16):X2}";
                                }
                                i++;
                            }
                        }
                    }
                    else
                    {
                        i += 4; // 如果没有足够的数据，跳过 4 个字节
                    }
                }
            }

            // 输出结果到文件的开关
            if (IsOutput)
            {
                using (StreamWriter writer = new StreamWriter($"{System.IO.Directory.GetCurrentDirectory()}\\Lib\\xc151_Bin\\B_BListSetting.txt"))
                {
                    // 将 blist 中的每个元素写入到文本文件
                    foreach (var item in blist)
                    {
                        writer.WriteLine($"原始{item.original} {item.module}_{item.smalladdr}_{item.dataexample}_{item.addresspart}_{item.addrsmallex}");
                    }
                }
            }

            return blist; // 返回更新后的 blist
        }


        /// <summary>
        /// 设置 ISP 的解析
        /// </summary>
        /// <param name="blist">BinBase 对象列表</param>
        public static void SetModeIsp(ref List<BinBase> blist)
        {
            // 获取头文件中设置区域的起始和结束索引
            var startHeaderIndex = blist.FindIndex(c => c.note != null && c.note.Contains("setting区0_00_首地址"));
            var endHeaderIndex = blist.FindLastIndex(c => c.note != null && c.note.Contains("Header_crc"));
            var nums = endHeaderIndex - startHeaderIndex;

            // 优化：只查找使能开关开启的地址
            var appENList = blist
                .Where(c => c.note != null && c.note.Contains("App setting区") && c.note.Contains("_en") && c.original == 1)
                .Select(c => c.note.Replace("_en", ""))
                .Distinct()
                .ToList();

            // 获取需要解析的结果集
            var result = blist.Skip(startHeaderIndex)
                              .Take(nums)
                              .Where(c => c.note != null && c.sort == 0x3 && appENList.Any(b => c.note.Contains(b)))
                              .ToList();

            // 遍历结果集
            foreach (var item in result)
            {
                // 处理 sort 为 0x3 的条目
                if (item.sort == 0x3)
                {
                    // 根据地址查找对应的位置
                    var sdata = Convert.ToInt32(item.smalldata, 16);
                    if (blist.Count <= sdata)
                    {
                        continue; // 若索引超出范围，则跳过
                    }

                    var t = blist[sdata];
                    var t1 = blist[sdata + 4];
                    int count = 0;

                    // 根据特定条件（地址和数据）计算需要的长度
                    if (t.smalladdr == "5843" && t.smalldata == "0151" && t1.smalldata != "0000")
                    {
                        count = Convert.ToInt32(t1.smalldata, 16) * 4; // 计算长度
                    }

                    // 添加过滤无效字段，设置无效字段 IsSetting 为 false
                    for (int i = 0; i < 4; i++)
                    {
                        blist[sdata + 4 + i].IsSetting = false;
                    }

                    // 获取需要处理的结果
                    var sResult = blist.Skip(sdata).Take(count).ToList();

                    // 查找 FFF8 和 FFF9 的解 ISP 连写模式
                    for (int j = 0; j < sResult.Count;)
                    {
                        // 检查是否满足条件
                        if (j + 4 < sResult.Count && sResult[j].smalladdr == "FFF8")
                        {
                            // FFF8 长度信息，FFF9 地址信息
                            var tlength = Convert.ToInt32(sResult[j].smalldata, 16); // 获取长度
                            var oddlegth = tlength % 4; // 剩余长度
                            var tAddr = 0; // 地址
                            var tIndex = 0; // 索引
                            int tempj = 0;

                            // 查找 FFF9 地址
                            for (int h = j; h < j + 8; h++)
                            {
                                if (sResult[h].smalladdr == "FFF9")
                                {
                                    tempj = h;
                                    break;
                                }
                            }
                            if (tempj != 0)
                            {
                                tAddr = Convert.ToInt32(sResult[tempj].smalldata, 16);
                                tIndex = blist.IndexOf(sResult[tempj], j) + 4;
                            }

                            // 处理有效地址范围
                            int tempAddr = tAddr + tlength;
                            for (int x = 0; x < tlength - oddlegth; x++)
                            {
                                var addr = ((4 + (x / 4) * 4) - ((x % 4) + 1) + tAddr);
                                blist[tIndex].smalladdr = addr.ToString("X4");
                                blist[tIndex].smalldata = blist[tIndex].original.ToString("X4");
                                blist[tIndex].IsIsp = true; // 标记为 ISP
                                tIndex++;
                            }

                            // 处理剩余长度
                            if (oddlegth > 0)
                            {
                                var oddAddr = tempAddr - oddlegth; // 调整地址
                                var oddIndex = tIndex + 3;

                                for (int i = 0; i < oddlegth; i++)
                                {
                                    blist[oddIndex].smalladdr = oddAddr.ToString("X4");
                                    blist[oddIndex].smalldata = blist[oddIndex].original.ToString("X4");
                                    blist[oddIndex].IsIsp = true; // 标记为 ISP
                                    oddIndex--;
                                    oddAddr++;
                                }

                                // 填写空缺地址为 FFFF
                                for (int i = 0; i < 4 - oddlegth; i++)
                                {
                                    blist[oddIndex].smalladdr = "FFFF";
                                    blist[oddIndex].IsIsp = true; // 标记为 ISP
                                    oddIndex--;
                                }
                            }

                            var tj = j + (int)Math.Ceiling(tlength / 4.0) * 4 + 8;
                            j = tj > j ? tj : j + 4; // 更新 j
                        }
                        else
                        {
                            j++; // 移动到下一个
                        }

                        #region 输出打印文件方便查看文件
                        if (count != 0 && IsOutput)
                        {
                            using (StreamWriter writer = new StreamWriter($"{System.IO.Directory.GetCurrentDirectory()}\\Lib\\xc151_Bin\\B_{item.note}.txt"))
                            {
                                for (int i = 0; i < sResult.Count(); i++)
                                {
                                    if (sResult[i].sort == 0x3)
                                    {
                                        writer.WriteLine($"{sResult[i].smallexample},//{sResult[i].addresspart} --{sResult[i].note} --{sResult[i].remarks}");
                                    }
                                }
                            }
                        }
                        #endregion
                    }
                }
            }

            // 如果需要输出结果，生成结果文件
            if (IsOutput)
            {
                #region 输出结果打印文件方便查看文件
                using (StreamWriter writer = new StreamWriter($"{System.IO.Directory.GetCurrentDirectory()}\\Lib\\xc151_Bin\\BB_setting.txt"))
                {
                    for (int i = 0; i < blist.Count(); i++)
                    {
                        if (i + 1 < blist.Count() && blist[i].smallexample != blist[i + 1].smallexample)
                        {
                            writer.WriteLine($"{blist[i].smallexample},//{blist[i].addresspart} --{blist[i].note} --{blist[i].remarks} -{blist[i].addrsmallex}");
                        }
                    }
                }
                #endregion
            }
        }


        /// <summary>
        /// 解析 setting区3_31 的连接关系地址并生成 LoadSettingParse 列表
        /// </summary>
        /// <param name="blist">BinBase 对象列表</param>
        /// <param name="lspList">LoadSettingParse 列表</param>
        public static void SetLoadSetting(ref List<BinBase> blist,ref List<LoadSettingParse> lspList)
        {
            // 筛选出符合条件的项
            var tlist = blist
                .Where(c => !string.IsNullOrEmpty(c.note) && c.note.Contains("setting区3_31_") && c.smalladdr.Contains("7E"))
                .ToList();

            // 初始化起始地址
            uint startL = 0x7E00;

            // 获取传输模式和视频模式的列表
            var tModel = VideoHelper.GetTransferMode();
            var vModel = VideoHelper.GetVideoMode();

            // 循环生成 LoadSettingParse 实例
            for (int i = 0; i < 49; i++)
            {
                LoadSettingParse model = new LoadSettingParse
                {
                    SettingHex = Convert.ToUInt16(i),
                    SettingName = $"setting区{Convert.ToUInt16(i) / 32}_{(Convert.ToUInt16(i) % 32).ToString().PadLeft(2, '0')}"
                };

                // 解析当前设置区域
                if (blist.Exists(c => !string.IsNullOrEmpty(c.note) && c.note.Contains(model.SettingName)))
                {
                    var tblist = blist.Where(c => !string.IsNullOrEmpty(c.note) && c.note.Contains(model.SettingName)).ToList();

                    // 查找包含 "FFF5" 的项
                    if (tblist.Exists(c => c.smalladdr.Contains("FFF5")))
                    {
                        var tbIndex = tblist.IndexOf(tblist.First(c => c.smalladdr.Contains("FFF5")));
                        var tbmodel = tblist[tbIndex + 5];

                        // 如果数据有效，解析传输模式和视频模式
                        if (tbmodel.smalldata != "0000")
                        {
                            model.tHex = Convert.ToUInt32(tbmodel.smalldata.Substring(0, 2), 16);
                            model.tName = tModel.Find(c => c.Hex.Contains(model.tHex.ToString("x2"))).Name;
                            model.vHex = Convert.ToUInt32(tbmodel.smalldata.Substring(2), 16);
                            model.vName = vModel.Find(c => c.Hex.Contains(model.vHex.ToString("x2"))).Name;
                        }
                    }
                }

                // 解析 TVE、IQ 和 Sensor 的地址和名称
                model.tveHex = Convert.ToUInt32((tlist.Find(c => c.smalladdr == startL.ToString("X4")) == null ? "0" : tlist.Find(c => c.smalladdr == startL.ToString("X4")).smalldata), 16);
                model.tveName = $"setting区{model.tveHex / 32}_{(model.tveHex % 32).ToString().PadLeft(2, '0')}";
                startL++; // 增加地址

                model.IqHex = Convert.ToUInt32((tlist.Find(c => c.smalladdr == (startL).ToString("X4")) == null ? "0" : tlist.Find(c => c.smalladdr == (startL).ToString("X4")).smalldata), 16);
                model.IqName = $"setting区{model.IqHex / 32}_{(model.IqHex % 32).ToString().PadLeft(2, '0')}";
                startL++; // 增加地址

                model.SensorHex = Convert.ToUInt32(tlist.Find(c => c.smalladdr == (startL).ToString("X4")) == null ? "0" : tlist.Find(c => c.smalladdr == (startL).ToString("X4")).smalldata, 16);
                model.SensorName = $"setting区{model.SensorHex / 32}_{(model.SensorHex % 32).ToString().PadLeft(2, '0')}";
                startL++; // 增加地址

                // 添加模型到列表
                lspList.Add(model);
            }

            // 输出结果到文件以供查看
            if (IsOutput)
            {
                #region 输出结果打印文件方便查看文件
                using (StreamWriter writer = new StreamWriter($"{System.IO.Directory.GetCurrentDirectory()}\\Lib\\xc151_Bin\\BB_lspListsetting.txt"))
                {
                    for (int i = 0; i < lspList.Count(); i++)
                    {
                        writer.WriteLine($"{lspList[i].Note}"); // 写入每个模型的 Note 信息
                    }
                }
                #endregion
            }
        }


        /// <summary>
        /// 根据宽度、高度和类型筛选 BinBase 列表，并生成键值对文件
        /// </summary>
        /// <param name="blist">BinBase 列表</param>
        /// <param name="usbList">SettingFileIDInfo 列表</param>
        /// <param name="_width">目标宽度</param>
        /// <param name="_height">目标高度</param>
        public static List<RegisterValue> GetAddrValData(List<BinBase> blist, List<SettingFileIDInfo> usbList, int _width, int _height)
        {
            // 筛选符合条件的 SettingFileIDInfo 列表
            var list = usbList
                .Where(c => (c.width == _width && c.height == _height && c.Type == SettingFileType.IQ_Config)
                             || c.Type == SettingFileType.IQ_Common)
                .ToList();

            // 存储符合条件的 BinBase 对象
            List<BinBase> lspTempList = new List<BinBase>();

            // 遍历筛选结果，将符合条件的 BinBase 对象添加到临时列表
            foreach (var item in list)
            {
                if (!string.IsNullOrEmpty(item.note))
                {
                    lspTempList.AddRange(blist.Where(c => !string.IsNullOrEmpty(c.note) && c.note.Contains(item.note)));
                }
            }

            // 存储 RegisterValue 对象
            List<RegisterValue> registerValues = new List<RegisterValue>();

            // 检查 addrsmallex 的最后四个字符是否为特定值
            var excludedSuffixes = new List<string> { "FFF7", "5843", "FFF5", "F6F5", "FFFD", "FFFE", "FFF8", "FFF9", "FFFF" };

            // 存储已经处理过的地址
            List<string> addrList = new List<string>();

            // 遍历临时列表，生成 RegisterValue 对象
            foreach (var item in lspTempList)
            {
                // 过滤地址位置小于8位的地址
                if (item.addrsmallex.Length < 8)
                {
                    continue;
                }
                // 检查最后四个字符
                if (item.addrsmallex.Length >= 4 && excludedSuffixes.Contains(item.addrsmallex.Substring(item.addrsmallex.Length - 4).ToUpper()))
                {
                    continue; // 如果最后四个字符匹配，则跳过
                }

                var sList = lspTempList.Where(c => c.addrsmallex.ToLower().Contains(item.addrsmallex.ToLower())).ToList();

                if (!sList.Any())
                {
                    continue; // 如果没有找到相应的地址，跳过此次循环
                }

                var index = blist.IndexOf(sList.Last());
                if (index == -1) // 检查是否在 blist 中找到
                {
                    continue; // 如果没有找到对应的索引，跳过
                }

                // 检查 addrList 中是否已经存在该 addrsmallex
                if (!addrList.Contains(item.addrsmallex))
                {
                    addrList.Add(item.addrsmallex); // 如果不存在，则添加

                    // 获取对应的值
                    var bModel = blist[index];
                    UInt32 val = 0xffff;

                    // 处理 ISP 和普通地址
                    if (bModel.IsIsp)
                    {
                        val = blist[index].original;
                    }
                    else
                    {
                        var sortList = sList.OrderBy(c => c.sort).Select(c => c.sort).Distinct().ToList();
                        try
                        {
                            if (sortList.Count == 4)
                            {
                                var bIndex = blist.FindLastIndex(c => c.addrsmallex.Contains(bModel.addrsmallex) && c.note.Contains(bModel.note) && c.AddrVal == AddressValueEnum.Val);

                                // 将两个 original 值按顺序合并成一个十六进制整数
                                val = (UInt32)((blist[bIndex].original << 8) | blist[bIndex - 1].original);
                            }
                            else if (sortList.Count == 8)
                            {
                                var BIndex = blist.FindLastIndex(c => c.addrsmallex.Contains(bModel.addrsmallex) && c.note.Contains(bModel.note) && c.AddrVal == AddressValueEnum.Val);
                                // 将四个 original 值按顺序合并成一个十六进制整数
                                val = (UInt32)((blist[BIndex].original << 24) | (blist[BIndex - 1].original << 16) | (blist[BIndex - 2].original << 8) | blist[BIndex - 3].original);
                            }
                            else
                            {
                                // 如果 sortList 的数量不是 4 或 8，则设置 val 为 FF00
                                val = 0xFF00;
                            }
                        }
                        catch (Exception ex)
                        {
                            // 记录异常或处理异常
                            logger.Debug($"{ex.ToString()}"); 
                            val = 0xFF00; // 在发生错误时设置 val 为 FF00
                        }
                    }
                    if (val != 0xffff)
                    {
                        // 创建 RegisterValue 对象并添加到列表Convert.ToUInt32(item.addrsmallex, 16), val, ""
                        registerValues.Add(new RegisterValue() { 
                        Address  = Convert.ToUInt32(item.addrsmallex, 16),
                        Value = val
                        });
                    }
                   
                   
                }
            }

            // 将键值对写入文件
            string directoryPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), "Lib", "xc151_Bin");
            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath); // 确保目录存在
            }

            string filePath = Path.Combine(directoryPath, "keyValuePairs.txt");
            using (StreamWriter writer = new StreamWriter(filePath))
            {
                foreach (var registerValue in registerValues)
                {
                    writer.WriteLine($"0x{registerValue.Address.ToString("X")}, 0x{registerValue.Value.ToString("X")}"); // 写入地址和值
                }
            }

            return registerValues; // 返回包含地址和值的 RegisterValue 列表
        }


        public static string GetAddrToVal(List<BinBase> blist, List<SettingFileIDInfo> usbList, int _width, int _height, string Addr) {
            var list = usbList.Where(c => (c.width == _width && c.height == _height && c.Type == SettingFileType.IQ_Config) || c.Type == SettingFileType.IQ_Common).ToList();
            List<BinBase> lspTempList = new List<BinBase>();
            foreach (var item in list)
            {
                lspTempList.AddRange(blist.Where(c => null != c.note && c.note.Contains(item.note)));
            }
            var sList = lspTempList.Where(c => c.addrsmallex.ToLower().Contains(Addr.Replace("0x", "").ToLower())).ToList();
            if (sList.Count <= 0)
            {
                return "";
            }
            var index = blist.IndexOf(sList.Last());
            if (index == 0)
            {
                return "";
            }
            var bModel = blist[index];
            if (bModel.IsIsp == true)
            {
                return blist[index].original.ToString("X");
            }
            else
            {
                var sortList = sList.OrderBy(c => c.sort).Select(c => c.sort).Distinct().ToList();
                if (sortList.Count == 4)
                {
                    var bIndex = blist.FindLastIndex(c => c.addrsmallex.Contains(bModel.addrsmallex) && c.note.Contains(bModel.note) && c.AddrVal == AddressValueEnum.Val);
                    return $"{  blist[bIndex ].original.ToString("X")}{blist[bIndex - 1].original.ToString("X")}";
                }
                else if (sortList.Count == 8)
                {
                    var BIndex = blist.FindLastIndex(c => c.addrsmallex.Contains(bModel.addrsmallex) && c.note.Contains(bModel.note) && c.AddrVal == AddressValueEnum.Val);
                    return $"{  blist[BIndex].original.ToString("X")}{ blist[BIndex - 1].original.ToString("X")}{blist[BIndex - 2].original.ToString("X") }{blist[BIndex - 3].original.ToString("X")}";
                }
            }

            return "";
        }
    }
}
